﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
#if ODIN_INSPECTOR
using Sirenix.OdinInspector;
#endif
// ReSharper disable CheckNamespace
// ReSharper disable InconsistentNaming
namespace com.susi.util.toolkit
{
    /// <summary>
    /// 兼容Odin
    /// </summary>
#if ODIN_INSPECTOR
    [ShowInInspector]
#endif
    [Obsolete("Not clearly idea")]
    public class EventTagCollection<TKey,TItem>:ICollection<TItem>,IDisposaEventer,IDisposaEventer<EventBag<TKey, TItem>>
        where TItem:class
    {
        public readonly EventBag<TKey,TItem> InnerBag;
        public readonly Func<TItem, TKey> KeySelector;

#pragma warning disable IDE1006 // 命名样式
        public event Func<TItem, bool> AddingFliter
        {
            add => InnerBag.AddingFliter += value;
            remove => InnerBag.AddingFliter -= value;
        }
        /// <summary>
        /// 当本对象释放的时候，RemovingFliter会被无视
        /// </summary>
        public event Func<TItem, bool> RemovingFliter
        {
            add => InnerBag.RemovingFliter += value;
            remove => InnerBag.RemovingFliter -= value;
        }
#pragma warning restore IDE1006 // 命名样式
        public event Action<TItem> onAddedEvent
        {
            add => InnerBag.onAddedEvent += value;
            remove => InnerBag.onAddedEvent -= value;
        }
        public event Action<TItem> onRemovedEvent
        {
            add => InnerBag.onRemovedEvent += value;
            remove => InnerBag.onRemovedEvent -= value;
        }
        public event Action onChangedEvent
        {
            add => InnerBag.onChangedEvent += value;
            remove => InnerBag.onChangedEvent -= value;
        }
        public event Action onDisposingEvent
        {
            add => InnerBag.onDisposingEvent += value;
            remove => InnerBag.onDisposingEvent -= value;
        }
        public event Action<EventBag<TKey, TItem>> onDisposingTEvent
        {
            add => InnerBag.onDisposingTEvent += value;
            remove => InnerBag.onDisposingTEvent -= value;
        }

        public EventTagCollection([NotNull] EventBag<TKey, TItem> innerBag, [NotNull] Func<TItem, TKey> keySelector)
        {
            InnerBag    = innerBag ?? throw new ArgumentNullException(nameof(innerBag));
            KeySelector = keySelector ?? throw new ArgumentNullException(nameof(keySelector));
        }
        public EventTagCollection([NotNull] Func<TItem, TKey> keySelector):this(new EventBag<TKey,TItem>(),keySelector)
        {

        }


        public int Count => InnerBag.SelectAllChildrenWithOutNull<TKey,EventList<TItem>,TItem>().Count();

        public bool IsReadOnly => false;

        public void Add(TItem item)
        {
            InnerBag.AddToInnerList(KeySelector(item),item);
        }

        public void Clear()
        {
            InnerBag.Clear();
        }

        public bool Contains(TItem item)
        {
            return InnerBag.Contains(item);
        }

        public void CopyTo(TItem[] array, int arrayIndex)
        {
            InnerBag.SelectAllChildrenWithOutNull<TKey, EventList<TItem>, TItem>().CopyTo(array, arrayIndex);
        }

        public IEnumerator<TItem> GetEnumerator()
        {
            return InnerBag.SelectAllChildrenWithOutNull<TKey, EventList<TItem>, TItem>().GetEnumerator();
        }

        public bool Remove(TItem value)
        {
            return InnerBag.RemoveValue(value);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return InnerBag.SelectAllChildrenWithOutNull<TKey, EventList<TItem>, TItem>().GetEnumerator();
        }

        bool ICollection<TItem>.Remove(TItem item)
        {
            return InnerBag.RemoveValue(item);
        }

        public void Dispose()
        {
            InnerBag.Dispose();
        }
    }
}
